package main

import (
	"database/sql"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"time"
)

//gorm demo02 创建

// User 定义模型
type User struct {
	gorm.Model   //内嵌gorm.Model（包含ID、CreatedAt、UpdatedAt、DeletedAt 四个字段）DeleteAt：调用 Delete 删除该记录时，将会设置 DeleteAt 为当前时间，而不是直接将记录从数据库中删除，通过判断 DeleteAt 是否为空，可以判断该记录是否已经被删除（俗称：软删除）
	Name         string
	Age          sql.NullInt64 //零值类型
	Birthday     *time.Time    `gorm:"column:user_birthday"` //6.使用 tag 指定 列名，而不使用默认的列名
	Email        string        `gorm:"type:varchar(100);unique_index"`
	Role         string        `gorm:"size:255"`        // 设置字段大小为255
	MemberNumber *string       `gorm:"unique;not null"` // 设置会员号（member number）唯一且不为空
	Num          int           `gorm:"AUTO_INCREMENT"`  // 设置 num 为自增类型
	Address      string        `gorm:"index:addr"`      //给 address 字段创建名为 addr 的索引
	IgnoreMe     int           `gorm:"-"`               //忽略本字段
}

// Animal 使用 `AnimalID` 作为主键
type Animal struct {
	AnimalID int64 `gorm:"primary_key"`
	Name     string
	Age      int64
}

// TableName 3.创建 TableName() 方法来指定表的名称
func (Animal) TableName() string {
	return "htl"
}

func main() {
	//5.GORM 还支持更改 默认表名称规则，不能修改自己指定的表名
	gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
		return "prefix_" + defaultTableName //给默认表名前再添加一个前缀
	}

	//连接 MySQL 数据库
	db, err := gorm.Open("mysql", "root:123456@(127.0.0.1:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	//禁用默认表名的复数形式，如果设置为 true，则 `User` 的默认表名是 `User`
	db.SingularTable(true)

	/*
		创建表 自动迁移（把结构体和数据表进行对应）：
			1.默认会使用 ID 字段作为 主键，如果没有该字段，可以通过 tag 来指定 主键（`gorm:"primary_key"`）
			2.表名：默认会是 结构体名称 的 复数
			3.也可以创建 TableName() 方法来指定表的名称
			4.也可以通过 Table() 指定表名
			5.GORM 还支持更改 默认表名称规则，不能修改自己指定的表名
			6.使用 tag 指定 列名，而不使用默认的列名 eg：`gorm:"column:user_birthday"`
			7.设置默认值 eg：`gorm:"default:'匿名'`（如果该字段为空，则默认值为 匿名）
			8.所有字段的 零值，比如 0，""，false..，都不会保存到数据库内，但会使用他们的默认值。如果想要避免这种情况，可以考虑使用指针或实现 Scanner/Valuer 接口（例子在 web21）
	*/
	db.AutoMigrate(&User{})
	db.AutoMigrate(&Animal{}) //1.默认会使用 ID 字段作为 主键，如果没有该字段，可以通过 tag 来指定 主键（`gorm:"primary_key"`）
	/*
		扩展创建选项：
			PostgreSQL数据库(MySQL数据库不行)中可以使用下面的方法实现 合并插入，有则更新，无则插入
	*/
	db.Set("gorm:insert_option", "ON CONFLICT").Create(&User{})

	//4.也可以通过 Table() 指定表名
	//使用 User 结构体 创建 名叫 swk 的 表
	db.Table("swk").CreateTable(&User{})

}
